"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" fjrti vim config
" fjrti@163.com
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
"
" basic configuration
"
if &compatible | set nocompatible | endif
set nocursorline
if exists('$TMUX') | set term=screen-256color | endif
set history=1000
filetype plugin on
filetype indent on
set autoread
set scrolloff=7
let $LANG='en'
set langmenu=en
set wildmenu
set wildmode=full
set wildignore+=*.o,*~,*.pyc,*/.git/*,*/.hg/*,*/.svn/*,*/.DS_Store
set wildignore+=*swp,*.class,*.pyc,*.png,*.jpg,*.gif,*.zip
set listchars=tab:\|\ ,trail:.,extends:>,precedes:<
set ruler
set hidden
set ttyfast
set ttymouse=xterm2
set viminfo+=!
set display=lastline
set fillchars=vert:│
set backspace=eol,start,indent
set whichwrap+=h,l,~,[,],<,>
set ignorecase
set smartcase
set hlsearch
set incsearch
set lazyredraw
set magic
set showmatch
set mat=1
set noerrorbells
set novisualbell
set splitright
set splitbelow
set autowrite
set mousehide
set linespace=0
set t_vb=
set t_ut=
syntax sync minlines=300
set fileformats=unix,dos,mac
set nobackup
set nowb
set noswapfile
set expandtab
set smarttab
set shiftwidth=4
set tabstop=4
set linebreak
set textwidth=500
set autoindent
set nowrap
set timeoutlen=500
set ttimeoutlen=200
set ttimeout
set nostartofline
set noshowmode
set updatetime=200
set laststatus=2
set pumheight=20
set winminheight=0
set cursorline
set cpt=.,k,w,b
" set completeopt=menu,menuone,noselect
set completeopt=menu,menuone
set shortmess+=c
" set shortmess=filnxtToO
set nowritebackup
set tags=./.tags;,.tags

let $LANG='en' 
set langmenu=en
set fileencodings=ucs-bom,utf-8,cp936,gb18030,big5,euc-jp,sjis,euc-kr,ucs-2le,latin1
set encoding=utf-8
" set encoding=chinese
set termencoding=chinese
set fileencoding=chinese
if v:lang =~ "utf8$" || v:lang =~ "UTF-8$"
    set encoding=utf-8
    set termencoding=utf-8
    set fileencoding=utf-8
endif

"
" key map
"
map <c-s> <nop>
command W w !sudo tee % > /dev/null
noremap <c-b> <left>
noremap <c-j> <down>
noremap <c-k> <up>
noremap <c-l> <right>
noremap <c-f> <right>
inoremap <c-b> <left>
inoremap <c-j> <down>
inoremap <c-k> <up>
inoremap <c-l> <right>
inoremap <c-a> <home>
inoremap <c-e> <end>
inoremap <c-d> <del>
inoremap <c-_> <c-k>
cnoremap <c-b> <left>
cnoremap <c-j> <down>
cnoremap <c-k> <up>
cnoremap <c-f> <right>
cnoremap <c-a> <home>
inoremap <c-a> <c-o>0
cnoremap <c-e> <end>
inoremap <c-e> <c-o>$
cnoremap <c-b> <left>
cnoremap <c-d> <del>
cnoremap <c-_> <c-k>
inoremap <c-u> <c-g>u<c-u>

" window management
noremap <silent><s-tab> :tabnext<cr>
inoremap <silent><s-tab> <ESC>:tabnext<cr>
nnoremap <bs> :b#<cr>
" set switchbuf=useopen,usetab,newtab
" set showtabline=2
nnoremap H ^
nnoremap L $
vnoremap v <Esc>
inoremap jj <esc>
inoremap jk <esc>
lmap     jk <esc>
inoremap j<space> j
nnoremap j gj
nnoremap k gk
vnoremap j gj
vnoremap k gk
nnoremap U <c-r>
nnoremap Y y$
nnoremap q <nop>
autocmd BufReadPost * if line("'\"") > 1 && line("'\"") <= line("$") | exe "normal! g'\"" | endif
autocmd BufReadPost quickfix nnoremap <buffer> <CR> <CR>
noremap f /
vnoremap f /
nnoremap F ?
vnoremap F ?
vnoremap < <gv
vnoremap > >gv
"select last pasted content
nnoremap gp `[v`]

"
" custom command
"
command! ZEnterCurrentDirectory call s:enter_current_directory()
command! ZRoot call s:enter_root_directory()
command! ZCleanTailspace call s:clean_tail_spaces()
command! ZDeleteDupBankLine call s:clean_dup_bank_line()
command! ZDosToUnix call s:dos_to_unix()
command! ZFindCursor call s:find_cursor()
command! ZReplace call s:local_file_replace(expand('<cword>'), 1)
command! ZDiffOrig vert new | set bt=nofile | r # | 0d_ | diffthis | wincmd p | diffthis
command! -nargs=? Filter let @a='' | execute 'g/<args>/y A' | new | setlocal bt=nofile | put! a
command! ZPath echo expand("%:p")
command! -bang ZForbiddenExit call s:forbidden_vim_exit(<bang>0)
command -nargs=0 -bar ZUpdate if &modified | if empty(bufname('%')) | browse confirm write | else | confirm write | endif |endif
command! -nargs=+ -complete=command ZMessage call s:tab_message(<q-args>)

"
" function
"
function! s:clean_tail_spaces()
    let save_cursor = getpos(".")
    let old_query = getreg('/')
    silent! %s/\s\+$//e
    call setpos('.', save_cursor)
    call setreg('/', old_query)
endfun

function! s:clean_dup_bank_line()
    let save_cursor = getpos(".")
    let old_query = getreg('/')
    silent! g/^\(\s*\)$\n\1$/d
    call setpos('.', save_cursor)
    call setreg('/', old_query)
endfun

function! s:dos_to_unix()
    silent! set fileformat=unix
    silent! w
endfun

function! s:tab_message(cmd)
    redir => message
    silent execute a:cmd
    redir END
    if empty(message)
        echoerr "no output"
    else
        " use "new" instead of "tabnew" below if you prefer split windows instead of tabs
        tabnew
        setlocal buftype=nofile bufhidden=wipe noswapfile nobuflisted nomodified
        silent put=message
    endif
endfunction

function! s:forbidden_vim_exit(flag)
    if a:flag == 0
        cabbrev q <c-r>=(getcmdtype()==':' && getcmdpos()==1 ? 'close' : 'q')<CR>
        cabbrev x <c-r>=(getcmdtype()==':' && getcmdpos()==1 ? 'echo "Lock quit"' : 'x')<CR>
        cabbrev quit <c-r>=(getcmdtype()==':' ? 'echo "Lock quit"' : 'quit')<CR>
        cabbrev exit <c-r>=(getcmdtype()==':' ? 'echo "Lock quit"' : 'exit')<CR>
        cabbrev wq <c-r>=(getcmdtype()==':' ? 'echo "Lock quit"' : 'wq')<CR>
        cabbrev wqa <c-r>=(getcmdtype()==':' ? 'echo "Lock quit"' : 'wqa')<CR>
        cabbrev qa <c-r>=(getcmdtype()==':' ? 'echo "Lock quit"' : 'qa')<CR>
        map ZZ <nop>
    else
        " TODO: has error
        exec 'cunabbrev q'
        exec 'cunabbrev x'
        exec 'cunabbrev quit'
        exec 'cunabbrev exit'
        exec 'cunabbrev wq'
        exec 'cunabbrev wqa'
        exec 'cunabbrev qa'
        exec 'unmap ZZ'
    endif
endfun

function! s:enter_current_directory()
    silent! cd %:p:h
    pwd
endfun

function! s:enter_root_directory()
    exec 'cd' fnameescape(fnamemodify(finddir('.git',
        \ escape(expand('%:p:h'), ' ') . ';'), ':h'))
    pwd
endfun

function! s:find_cursor()
    set cursorline cursorcolumn
    redraw
    sleep 500m
    " TODO
    set nocursorline nocursorcolumn
endfunction

function! s:echo_warning(msg)
  echohl WarningMsg
  echo "Warning"
  echohl None
  echon ': ' a:msg
endfunction

" local file replace, alike with easygrep
function! s:local_file_replace(str, wholeword)
    echon "Replace [" | echohl WarningMsg | echon a:str | echohl None | echon "] in current file with: "
    let r = input("", a:str)
    if empty(r)
        let confirmed = confirm("Proceed replacing '".a:str."' with an empty pattern, effectively deleting it?", "&Yes\n&No")-1
        if confirmed
            return
        endif
    endif
    if r ==# a:str
        echo " "
        echo "No change in pattern, ignoring"
        return
    endif

    " start replace
    let save_cursor = getpos(".")
    exec '%s/\<'.a:str.'\>/'.r.'/g'
    call setpos('.', save_cursor)
endfunction

" :e this/does/not/exist/file.txt
" :w
function s:Mkdir()
  let dir = expand('%:p:h')
  if dir =~ '://'
    return
  endif
  if !isdirectory(dir)
    call mkdir(dir, 'p')
    echo 'Created non-existing directory: '.dir
  endif
endfunction
autocmd BufWritePre * call s:Mkdir()

" for jumplist
function! GotoJump()
  jumps
  let j = input("Please select your jump: ")
  if j != ''
    let pattern = '\v\c^\+'
    if j =~ pattern
      let j = substitute(j, pattern, '', 'g')
      execute "normal " . j . "\<c-i>"
    else
      execute "normal " . j . "\<c-o>"
    endif
  endif
endfunction

" jumplist, leader jump
nnoremap <space>gj :call GotoJump()<CR>

